====== Navigation in the Questionnaire ======

Participants usually start on the first page and then fill out the questionnaire sequentially. The sequence can be changed with ''[[:en:create:functions:setpageorder]]'' or ''[[:en:create:functions:gotopage]]]'', but the participants still follow the sequence given by the project manager.

This tutorial describes how to add a menu or navigation to the questionnaire so that participants can jump between pages and/or sections. This is especially useful when using a form in SoSci Survey to get specific information of your participants  (see also [[:en:create:mix-forms]]).

{{:de:create:scr.navigation.result1.png?nolink|Example for a navigation menu in the questionnaire}}


===== Basics =====

Step one is to fill the IDs on every page which your participants can jump to, under "Compile Questionnaire". Enter the title of your page as //Note//.

{{:de:create:scr.navigation.pageid.png?nolink|Enter page ID and note}}

The navigation buttons are created by the function ''[[:de:create:functions:buttontopage]]''. This function generates HTML-Code, which can be implemented in the questionnaire page using ''[[:en:create:functions:html]]''. With the following PHP-code you are able to create buttons on a questionnaire page with different purposes.

<code php>
html(
  '<div>'
  buttonToPage('start').
  buttonToPage('contact').
  buttonToPage('study').
  buttonToPage('services').
  buttonToPage('documents').
  buttonToPage('notes').
  buttonToPage('submit').
  '</div>'.
);
</code>

{{:de:create:scr.navigation.result2.png?nolink|Buttons for navigation between different pages}}

The PHP-Code is required on every page (e.g. at the top) of your questionnare to be enabled. This is very inconvenient and makes subsequent changes more difficult. Therefore, you define a new function that manages the navigation and any further adjustments. It is located under **Compile Questionnare** in the tab *PHP Functions*. 


<code php>
function navigation() {
    // Navigation
    html(
      '<div>'
      buttonToPage('start').
      buttonToPage('contact').
      buttonToPage('study').
      buttonToPage('services').
      buttonToPage('documents').
      buttonToPage('notes').
      buttonToPage('submit').
      '</div>'.
    );
    // Label of the Next button
    option('nextbutton', 'next form');
}
</code>

To enable the function, the following PHP-Code is needed on each page of your questionnare:

<code php>
navigation();
</code>


===== Layout Customization =====

The layout of the page and its buttons can be changed with CSS.
First some HTML-Code additions are required:

  * In the outer ''<div>'' block element, the ''style'' attribute adds a grey ''border'' at the top and bottom,
  * around the buttons another ''<div>'' block element is added with a CSS-class (in the example "NavButtons"). The additional class ''s2flex'' allows to use the whole width.
  * Between the buttons for "notes" and "send" an empty ''<div>'' element is added to create some space between the buttons.

<code php>
html(
  '<div style="border: 2px solid #CCCCCCCC; border-left: 0 none; border-right: 0 none; padding: 20px 0 12px 0; margin-bottom: 3em;">'.
  '<div class="s2flex NavButtons" style="flex-wrap: wrap; margin-right: -8px">'.NL.
  buttonToPage('start').
  buttonToPage('contact').
  buttonToPage('study').
  buttonToPage('services').
  buttonToPage('documents').
  buttonToPage('notes').
  '<div style="width: 2em;"></div>'.
  buttonToPage('submit').
  '</div>'.
  '</div>'.
);
</code>

In the **HTML-Template** you need to add CSS-statements within the ''<style>'' section matching your [[:en:create:layout|Survey Layout]]:

<code css>
div.NavButtons button {
  border: 2px solid %color.4%;
  border radius: 5px;
  padding: 7px 6px;
  margin-bottom: 8px;
  flex-grow: 1;
  margin-right: 8px;
}
div.NavButtons button.currentPage {
  background color: %color.4%;
  color: white;
}
</code>

The second block (''button.currentPage'') ensures that the navigation button of the current page is highlighted. The function ''buttonToPage()'' assigns the CSS-class ''currentPage'' to the button which refers to the current page.


===== Progress Indication =====

If there is no given order of answering the questions, you might want to show your participants their progress on your survey.
For example by showing your participants which pages are complete and which are incomplete. 

{{:de:create:scr.navigation.result3.png?nolink|Navigation with display of the completion status}}

Therefore you add further CSS-declarations in your questionnare-layout, which show a green hook next to complete pages, and a red cross next to the name of incomplete pages. Both icons are defined in the UTF-8-character set and can be used by their character-codes (2713 and 274C). The current page should not show an icon.

<code css>
div.NavButtons button.complete:after { content: " \2713"; }
div.NavButtons button.incomplete:after { content: " \274C"; }
div.NavButtons button.currentPage:after { content: none; }
</code>

Whether or not the page is completely filled in, the PHP code must check the completeness by using  ''[[:en:create:functions:value]]'' or ''[[:en:create:functions:getItems]]'' respectively. The CSS-classes ''complete'' and ''incomplete'' can then be specified as the fourth parameter in the function ''[[:en:create:functions:buttontopage]]''. The second and third parameters remain empty with ''NULL''.

The affiliated PHP-code is saved in *PHP-Functions* of your questionnare and could look like this:

<code php>
function navigation() {
    // Completion check
    $cContact = (count(array_merge(
        checkItem('KD02', 'KD01_01'),
        checkQst('KD01', [2,3,4,5,6,8]),
        checkItem('KD03', 'KD01_07')
    )) === 0);
    
    $cStart = (
      (count(array_intersect(getItems('KD01', 'valid'), [2,3,4,5,6,8])) == 6) and
      (value('KD02') > 0) and
      ((value('KD03') > 0) or (value('KD03') == -2)
    );
    
    // Here you can run additional checks on ...
    // "study" -> $cStudy
    // "services" -> $cServices
    // "documents" -> $cDocuments
    // ... and so on.
    
    
    // Navigation
    html('<div style="border: 2px solid #CCCCCC; border-left: 0 none; border-right: 0 none; padding: 20px 0 12px 0; margin-bottom: 3em;">'.
      '<div class="s2flex NavButtons" style="flex-wrap: wrap; margin-right: -8px">'.NL.
      buttonToPage('start').
      buttonToPage('contact', NULL, NULL, ($cContact ? 'complete' : 'incomplete')).
      buttonToPage('study', NULL, NULL, ($cStudy ? 'complete' : 'incomplete')).
      buttonToPage('study', NULL, NULL, ($cServices ? 'complete' : 'incomplete')).
      buttonToPage('documents', NULL, NULL, ($cDocuments ? 'complete' : 'incomplete')).
      buttonToPage('notes').
      '<div style="width: 2em;"></div>'.
      buttonToPage('submit').
      '</div>'.
      '</div>'.
    );
    option('nextbutton', 'next form');
}


function checkQst($qID, $items) {
  $fail = [];
  foreach ($items as $item) {
    $answer = value(id($qID, $item));
    if (($answer < -3) or ($answer === '')) {
      $text = preg_replace('/:.*/', '', getItemtext($qID, $item))
      $fail[] = $text;
    }
  }
  return $fail;
}

function checkItem($varIDs, $textID) {
  $fail = [];
  if (!is_array($varIDs)) {
    $varIDs = [$varIDs];
  }
  foreach ($varIDs as $varID) {
    $answer = value($varID);
    if (($answer < -3) or ($answer === '')) {
      $text = preg_replace('/:.*/', '', getItemtext($textID));
      $fail[] = $text;
      // Only one of them
      break;
    }
  }
  return $fail;
}
</code>

The following code snippet is responsible for assigning the CSS-class ''complete'' or ''incomplete'', which is entered in varied form as the fourth parameter in the function ''buttonToPage()'':

<code php>
    ($cContact ? 'complete' : 'incomplete')
</code>

In this particular example the buttons "start", "notes" and "send" don't have a progress indication.

The PHP-code for the progress indication depends on the individual case of your survey. The functions ''checkQst()'' and ''checkItem()'' can be helpful in any case. In addition to that, they are created to show your participants a list of missing statements. Those missing statements are shown in a list on the page "submit".

Individual checks may also become more complicated and must be outsourced to separate functions.

<code php>
    $cStudy = (count(checkStudy()) === 0);
    $cServices = (count(checkECTS()) === 0);
    $cDocuments = (count(checkDocs()) === 0);
</code>